
 class MyEvent {
    constructor() {
        this.handler = {};
    }
    // 添加事件
    addEvent(eventName, fn) {
        // 通过 handle 来保存下来，等到需要执行的时候在执行
        // {自定义事件名(click):[fn1,fn2,fn3...]}
        if (typeof this.handler[eventName] == "undefined") {
            // 把对象初始化成一个数组
            this.handler[eventName] = [];
            // {myevent:[fn,fn1,fn2]}
        }
        this.handler[eventName].push(fn)
    }
    trigger(eventName,pyload) {
        this.handler[eventName].forEach(fn => {
            fn(pyload);
        })
    }
}



class Vue extends MyEvent{
    constructor(options){
        super();
        this.$el = options.el;
        this._data = options.data;
        // 把数据渲染到视图 
        this.compile();
        this.Observe(this._data);
    }
     Observe(data){
            let keys = Object.keys(data);
            let _this = this;
            keys.forEach(key=>{
                let value = data[key];
                Object.defineProperty(data,key,{
                    configurable:true,
                    enumerable:true,
                    get(){
                        console.log("get")
                        return value;
                    },
                    set(newvalue){
                        // console.log(this);
                        console.log("新值",newvalue);
                        // 自定义事件名  key ---> message
                        _this.trigger(key,newvalue)
                        // 
                        value = newvalue;
                    }
                })
            })
        }


    // 观察数据，数据变动的时候做出视图的响应
    // 编译
    compile(){
        // 获取到app作用域
        // #app范围
        let ele = document.querySelector(this.$el);
        this.compileNodes(ele);
    }
    compileNodes(ele){
        console.log(this);  // 需要用的是实例化对象的this
        // 获取 作用域下面的所有节点
        let childs = ele.childNodes;
        // console.log(childs)
        childs.forEach(node=>{
            // 获取所有的文本节点
            if(node.nodeType===3){
                // console.log( node);
                // 文本获取到了 ，在文本里查找 插值表达式 {{afdsafdsa}}
                // ? + * 
                let reg = /{{\s*([^{}\s]+)\s*}}/g;
                // 通过文本节点获取文本 
                let content = node.nodeValue;
                if(reg.test(content)){
                    // console.log(content);
                    let $1 = RegExp.$1;
                    // console.log(this._data[$1]);
                    // console.log("("+$1+")");
                    node.nodeValue = node.nodeValue.replace(reg,this._data[$1]);
                     // 绑定事件
                    this.addEvent($1,(newvalue)=>{
                        // console.log("??",newvalue);
                        let oldvalue = this._data[$1];
                        let reg = new RegExp(oldvalue);
                        node.nodeValue = node.nodeValue.replace(reg,newvalue);
                    })
                
                }
                // console.log(typeof content);
            }else if(node.nodeType===1){
                // 获取 元素的属性节点
                let attrs = node.attributes
                console.log(attrs);

                [...attrs].forEach(attr=>{
                    console.log(attr);
                    // 获取属性名
                    let attrname = attr.name;
                    // 属性值
                    let attrvalue = attr.value;
                    if(attrname=="v-html"){
                        node.innerHTML = this._data[attrvalue];
                    }else if(attrname == "v-text"){
                        node.innerText = this._data[attrvalue];
                    }else if(attrname == "v-model"){
                        node.value = this._data[attrvalue];
                        node.addEventListener("input",e=>{
                            // console.log(e.target.value);
                            // 又触发 set
                            this._data[attrvalue] = e.target.value;
                        })
                    }

                })

                // 元素节点
                this.compileNodes(node);
            }
        })
    }

}